package com.foohoo.benchmark.cpu;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 测试CPU缓存行对性能的提升
 * Benchmark           Mode  Cnt   Score    Error  Units
 * CacheLine.colFirst  avgt    3  14.679 ± 43.960  ns/op
 * CacheLine.rowFirst  avgt    3   4.153 ±  1.457  ns/op
 * 一句话结论: 横向遍历的情况下，cpu能连续读取同一个缓存行里边连续的几个对象，从而大幅提高性能(纵向遍历时前后两个对象不在同一个缓存行内)
 *
 * @author mzdbxqh
 * @date 2020-10-22 15:22
 **/
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 3, time = 1)
@Fork(1)
@Threads(1)
@State(Scope.Benchmark)
public class CacheLine {

	private final static int COUNT = 4096;

	private final static int MATRIX_SIZE = COUNT * COUNT;

	private int[][] matrix;

	@Setup
	public void setup() {
		matrix = new int[COUNT][COUNT];
		Random random = new Random(1234);
		for (int i = 0; i < COUNT; i++) {
			for (int j = 0; j < COUNT; j++) {
				matrix[i][j] = random.nextInt();
			}
		}
	}

	@Benchmark
	@OperationsPerInvocation(MATRIX_SIZE)
	public void colFirst(Blackhole bh) {
		for (int c = 0; c < COUNT; c++) {
			for (int r = 0; r < COUNT; r++) {
				bh.consume(matrix[r][c]);
			}
		}
	}

	@Benchmark
	@OperationsPerInvocation(MATRIX_SIZE)
	public void rowFirst(Blackhole bh) {
		for (int r = 0; r < COUNT; r++) {
			for (int c = 0; c < COUNT; c++) {
				bh.consume(matrix[r][c]);
			}
		}
	}

}
